#import "template.typ": book
#show: rest => book("Apache ECharts 使用说明书", rest)

#show regex("JS\W+"): "JavaScript" // 把 JS 替换为 JavaScript

= 简介

Apache ECharts @echarts 是一个基于 JS 的开源可视化图表库。2013 年百度成立 ECharts 项目，2018 年 1 月 ECharts 进入 Apache 孵化器，并于 2021 年 1 月成为 Apache 顶级项目。

== 安装

使用 Vite 创建纯 JS 项目，并安装 echarts 依赖。

```sh
# 基于 Vite 创建纯 JS 项目
$ pnpm create vite echarts-demo

# 进入项目目录
$ cd echarts-demo

# 安装项目基础依赖
$ pnpm install

# 安装 echarts 依赖
$ pnpm add echarts

# 启动开发服务器
$ pnpm run dev
```

== 第一个图表

修改 `index.html` 文件，为 `<div id="app">` 添加宽高尺寸，如下：

```html
<div id="app" style="width: 500px; height: 400px">
</div>
```

修改 `main.js`，引入 `echarts` 并创建图表示例，传入选项后，创建一个折线图。

```js
import * as echarts from 'echarts'

// 初始化图表实例
const el = document.querySelector('#app')
const myChart = echarts.init(el)

// 设定图表选项
const option = {
  xAxis: {
    type: 'category', // x 轴是类目轴
    data: ['A', 'B', 'C', 'D'],
  },
  yAxis: {
    type: 'value', // y 轴是数值轴
  },
  series: [
    {
      type: 'line', // 折线图
      data: [9, 5, 2, 7],
    },
  ],
}

// 渲染图表
myChart.setOption(option)
```

绘制的图形如下所示：

#figure(
    image("assets/first-chart.png"),
    caption: [第一张图表]
) <first-chart>

#pagebreak()

= 概念

== 图表容器

`echarts.init()` 的第一个参数是图表容器，在第一张图表 @first-chart 中，我们通过内联 CSS 样式指定了容器尺寸。

如果未使用样式指定尺寸，也可以通过 `echarts.init()` 第 3 个参数指定。

```js
echarts.init(el, null, { width: 800, height: 600 })
```

=== 动态改变尺寸

如果容器尺寸随页面尺寸动态变化，可以监听页面的 `resize` 事件，当页面尺寸改变时，调用图表实例的 `resize()` 方法 @chart-size。

举个例子，我们想全屏显示图表，可以这么做：

```html
<!-- file: index.html -->
<style>
    html, body { margin: 0; padding: 0; }
    #app { width: 100vw; height: 100vh; }
</style>

<div id="app"></div>
<script type="module" src="/main.js"></script>
```

```js
// file: main.js

// ...
const el = document.querySelector('#app')
const myChart = echarts.init(el)

window.addEventListener('resize', () => {
    myChart.resize()
})
```

`resize()` 也可以传入明确的尺寸数据。比如：

```js
myChart.resize({
    width: 800,
    height: 400
})
```

=== 销毁与重建

当图表容器被销毁时，总是调用图表实例的 `dispose()` 方法，防止内存泄露。当容器被再次添加，执行 `echarts.init()` 重新创建图表实例。

```js
let myChart;

// 假设这是容器创建后的回调函数
function onContainerCreated() {
    // 重建图表实例
    myChart = echarts.init(el)
    // ...
}

// 假设这是容器销毁后的回调函数
function onContainerDestroyed() {
    // 销毁图表实例
    myChart?.dispose()
}
```

#pagebreak()

#bibliography("bib.yml", title: "参考文献")